package com.zh.juc.lock;

import java.util.concurrent.TimeUnit;

/**
 * @Author: zhanghuan
 * @date: 2022/10/7 19:47
 * @description: create it
 */
class Phone {
    /**
     * 同步方法
     */
    public static synchronized void sendEmail() {

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("sendEmail....");
    }

    /**
     * 同步方法
     */
    public synchronized void sendSMS() {
        System.out.println("sendSMS....");
    }


    /**
     * 普通方法
     */
    public void hello() {
        System.out.println("hello.....");
    }
}

/**
 * 8锁案例说明
 * 1.标准访问有ab两个线程，请问先打印邮件还是短信
 * 2.sendEmail方法暂停3秒，请问先打印邮件还是短信
 * 3.添加一个普通的hello方法，请问先打印邮件还是hello
 * 4.有两部手机，请问先打印邮件还是短信
 * 5.有两个静态同步方法，有1部手机，请问先打印邮件还是短信
 * 6.有两个静态同步方法，有2部手机，请问先打印邮件还是短信
 * 7.有1个静态方法，有1个普通方法，有1部手机，请问先打印邮件还是短信
 * 8.有1个静态方法，有1个普通方法，有2部手机，请问先打印邮件还是短信
 * <p>
 * 总结：
 * 一个对象里面如果有多个synchronized方法，某一时刻，只有有一个线程去调用其中一个synchronized方法，其他线程就会等待。
 * 某一个时刻，只能有唯一一个线程访问这些synchronized方法。synchronized锁的是当前对象this。
 * <p>
 * static synchronized锁的是类。
 * <p>
 * 对于普通同步方法,锁的是当前实例对象，通常指this,
 * 对于静态同步方法，锁的是当前类的Class对象
 * 对于同步代码块，锁的是synchronized括号内的对象
 */


public class Lock8Demo {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            phone1.sendEmail();
        }, "a").start();

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            // phone.sendSMS();
            phone1.sendSMS();
        }, "b").start();
    }
}
